package kr.co.spring329.sample.quartz;

import java.net.InetAddress;
import java.util.List;

import kr.co.spring329.sample.model.ScheduleJobListVO;
import kr.co.spring329.sample.service.ScheduleExecuteService;
import kr.co.spring329.sample.service.ScheduleJobListService;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerBean;

/**
 * 스케줄러 생성을 DB에 있는 데이터를 읽어서 동적으로 생성하기 위해 
 * SchedulerFactoryBean 을 상속받은 클래스를 생성
 */
public class SchedulerFactoryBeanWrapper extends SchedulerFactoryBean
{
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	private String serverHostName = null; // DB에 저장된 호스트네임
	
	private String nowServerHostName = null; // 현재 서버의 호스트네임
	
	@Autowired
	private ScheduleJobListService scheduleJobListService;
	
	@Autowired
	private ScheduleExecuteService scheduleExecuteService;
	
	private Scheduler scheduler;
	
	/**
	 * jobDetail.setGroup(Scheduler.DEFAULT_GROUP); 생략하면 디폴트 그룹으로 설정
	 * trigger.setGroup(Scheduler.DEFAULT_GROUP); 생략하면 디폴트 그룹으로 설정
	 * @throws Exception
	 */
	public void init() throws Exception
	{		
		this.logger.debug("======================= SchedulerFactoryBeanWrapper.init() START =======================");
		
		this.scheduler = super.getScheduler();
		
		this.serverHostName = this.scheduleJobListService.getServerHostName();
		this.nowServerHostName = InetAddress.getLocalHost().getHostName();
		
		List<ScheduleJobListVO> jobList = this.scheduleJobListService.listJobList();
		
		for(int i = 0; i < jobList.size(); i++)
		{
			ScheduleJobListVO jobListVO = (ScheduleJobListVO)jobList.get(i);
			
			MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
			jobDetail.setBeanName(jobListVO.getJobName());
			jobDetail.setTargetObject(this.scheduleExecuteService);
			jobDetail.setTargetMethod(jobListVO.getExecuteMethod());
			jobDetail.setConcurrent(false);
			jobDetail.afterPropertiesSet();
			
			if(jobListVO.getBatchType().equals("cron"))
			{
				CronTriggerBean cronTriggerBean = new CronTriggerBean();
				cronTriggerBean.setBeanName(jobListVO.getTriggerName());
				cronTriggerBean.setDescription(jobListVO.getDescription());
				cronTriggerBean.setJobDetail((JobDetail)(jobDetail.getObject()));
				cronTriggerBean.setCronExpression(jobListVO.getCronExpression());
				cronTriggerBean.setStartDelay(30000);
				cronTriggerBean.afterPropertiesSet();
				
				this.scheduler.scheduleJob((JobDetail)(jobDetail.getObject()), cronTriggerBean);
			}
			else
			{
				SimpleTriggerBean simpleTriggerBean = new SimpleTriggerBean();
				simpleTriggerBean.setBeanName(jobListVO.getTriggerName());
				simpleTriggerBean.setDescription(jobListVO.getDescription());
				simpleTriggerBean.setJobDetail((JobDetail)(jobDetail.getObject()));	
				simpleTriggerBean.setRepeatInterval(Long.parseLong(jobListVO.getCronExpression()));
				simpleTriggerBean.setStartDelay(30000);
				simpleTriggerBean.afterPropertiesSet();
				
				this.scheduler.scheduleJob((JobDetail)(jobDetail.getObject()), simpleTriggerBean);
			}
		}
		
		// DB에 저장된 호스트네임과 현재 서버의 호스트네임이 같으면 스케줄러 실행
		if(this.serverHostName.equals(this.nowServerHostName))
			this.scheduler.start();

		jobList = null;
	}
	
	public void destroy() throws SchedulerException
	{
		super.destroy();
	}
}






























